package com.cip.master.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.cip.admin.model.Staff;
import com.cip.admin.model.User;
import com.cip.admin.service.ImportFileService;
import com.cip.admin.service.RoleManager;
import com.cip.admin.service.StaffService;
import com.cip.admin.service.UserManager;
import com.cip.common.util.SecurityUtil;
import com.cip.master.model.Academic;
import com.cip.master.model.ClassYear;
import com.cip.master.model.ExamPaper;
import com.cip.master.model.Examination;
import com.cip.master.model.Result;
import com.cip.master.model.Section;
import com.cip.master.model.Subject;
import com.cip.master.service.AcademicService;
import com.cip.master.service.ClassYearService;
import com.cip.master.service.ExaminationService;
import com.cip.master.service.ResultService;
import com.cip.master.service.SectionService;
import com.cip.master.service.SubjectService;
import com.cip.webapp.action.BaseAction;

public class ImportFileAction extends BaseAction {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public static final Log logger = LogFactory.getLog(com.cip.master.action.ImportFileAction.class);	
	private File fileUpload;
	private String screenName;
	private ImportFileService importFileService;
	private ResultService  resultService;
	private ExaminationService examService;
	private ClassYearService classYearService;
	private AcademicService  academicService;
	private SectionService sectionService;
	private UserManager userManager;
	private SubjectService  subjectService;
	private StaffService staffService;
	private InputStream fileInputStream;
	private RoleManager roleManager;
	private String filename;
	private List<Academic> academicList;
	private List<Examination> examList;
	private List<ClassYear> classYears;
	private List<Section> sectionList;
	private List<Subject> subjectList;
	private String academicYear;
	private String classYear;
	private String sectionName;
	private String examName;
	private String subjectName;
	 
	
	public String showImportFile() throws Exception{
		setAcademicList(academicService.getAllAcademicList());
		setClassYears(classYearService.getAllClassYear());
		setExamList(examService.getAllExamList());
		setSectionList(sectionService.getAllSection());	
		setSubjectList(subjectService.getAllSubjectList());
		return SUCCESS;
	}
	
	public String importFile(){
		try{
			List<Map<String, String>> csvValues = importFileService.getDataFromCSV(fileUpload);
			for (Map<String, String> map : csvValues) {
				if(getScreenName().equalsIgnoreCase("Result")){
					saveResults(map);
				}else if (getScreenName().equalsIgnoreCase("Class")) {
					saveClassYear(map);
				}else if (getScreenName().equalsIgnoreCase("Section")) {
					saveSection(map);
				}else if (getScreenName().equalsIgnoreCase("Staff")) {
					saveStaff(map);
				}else if (getScreenName().equalsIgnoreCase("Student")) {
					saveStudent(map);
				}else if (getScreenName().equalsIgnoreCase("Subject")) {
					saveSubject(map);
				}else if (getScreenName().equalsIgnoreCase("Examination")) {
					saveExamination(map);
				}				
			}
			saveMessage(getText("importFile.upload"));
			
		}catch (Exception e) {
			e.printStackTrace();
			logger.error(getText("importFile.uploadError")+e.getMessage(),e);
			addActionError(getText("importFile.uploadError")+e.getMessage());
		}finally{
			try{
				setAcademicList(academicService.getAllAcademicList());
				setClassYears(classYearService.getAllClassYear());
				setExamList(examService.getAllExamList());
				setSectionList(sectionService.getAllSection());	
				setSubjectList(subjectService.getAllSubjectList());
			}catch (Exception e) {
				logger.error(getText("importFile.uploadError")+e.getMessage());
				addActionError(getText("importFile.uploadError")+e.getMessage());
			}
						
		}
		return SUCCESS;
	}
	
	public String downloadFileTemplate() throws Exception{
		String[] header = new String[]{};
		List<String> headerList = new ArrayList<String>();	
		List<String[]> recordList = new ArrayList<String[]>();
		if(getScreenName().equalsIgnoreCase("Result")){
			List<User> userList = userManager.getAllCandidatesByClass(Integer.valueOf(getClassYear()), Integer.valueOf(getSectionName()));
			int sNo = 1;
			for (User user : userList) {
				String[] record = new String[4];				
				record[0] =String.valueOf(sNo); 	
				record[1] = user.getFirstName()+user.getLastName();
				record[2] = String.valueOf(user.getId());
				sNo++;
				recordList.add(record);
			}
			headerList.add("SNo");
			headerList.add("studentName");
			headerList.add("studentID");
			if(!getSubjectName().isEmpty()	){
				Subject subject = subjectService.getSubjectById(Integer.valueOf(getSubjectName()));
				headerList.add("subjectCode#"+subject.getCode()+"-"+subject.getSubjectName());
			}else{
				List<ExamPaper> examPapers= examService.getExamPapersByExam(Integer.valueOf(getExamName()));
				for (ExamPaper examPaper : examPapers) {
					Subject subject = subjectService.getSubjectById(Integer.valueOf(examPaper.getSubjectId()));
					headerList.add("subjectCode#"+subject.getCode()+"-"+subject.getSubjectName());				
				}
			}
						
		}else if (getScreenName().equalsIgnoreCase("Class")) {
			headerList.add("SNo");
			headerList.add("Class");
		}else if (getScreenName().equalsIgnoreCase("Section")) {
			headerList.add("SNo");
			headerList.add("Class");
			headerList.add("Section");
		}else if (getScreenName().equalsIgnoreCase("Staff")) {
			headerList.add("SNo");
			headerList.add("firstName");
			headerList.add("lastName");
			headerList.add("gender");
			headerList.add("martialStatus");
			headerList.add("qualification");
			headerList.add("contactNumber");
		}else if (getScreenName().equalsIgnoreCase("Student")) {
			headerList.add("SNo");
			headerList.add("username");
			headerList.add("firstName");
			headerList.add("lastName");
			headerList.add("email");
			headerList.add("phoneNumber");
			headerList.add("address");
		}else if (getScreenName().equalsIgnoreCase("Subject")) {
			headerList.add("SNo");
			headerList.add("Class");
			headerList.add("SubjectCode");
			headerList.add("SubjectName");			
		}else if (getScreenName().equalsIgnoreCase("Examination")) {
			headerList.add("SNo");
			headerList.add("Class");
			headerList.add("Examination");			
		}		
 		File file = importFileService.writeDataInCSV(headerList.toArray(new String[headerList.size()]), recordList, getRequest().getParameter("screenName")+".csv");//getRequest().getParameter("screenName")+".csv";
		setFilename(file.getName());
		//String filePath ="/home/simbu/CIP/"+file;
		fileInputStream = new FileInputStream(file);		  
		return SUCCESS;
	}
	
	public void saveResults(Map<String, String> csvValues) throws Exception{
		try{
			ClassYear classYear = classYearService.getClassYear(Integer.parseInt(getClassYear()));
			Section section = sectionService.getSection(Integer.parseInt(getSectionName()));
			Examination exam = examService.getExamById(Integer.parseInt(getExamName()));
			Academic academic = academicService.getAcademicById(Integer.parseInt(getAcademicYear()));
			User user = userManager.getUser(csvValues.get("studentID"));
			User loggedinuser = SecurityUtil.getThreadLocalUser().get();
			Subject subject = null;
			if(!subjectName.isEmpty()	){
				subject = subjectService.getSubjectById(Integer.parseInt(getSubjectName()));
				Result result = new Result();
				result.setClassYear(classYear);
				result.setSection(section);
				result.setExamination(exam);
				result.setSubject(subject);
				result.setAcademic(academic);
				result.setUser(user);
				result.setMark(Integer.parseInt("subjectCode#"+subject.getCode()+"-"+subject.getSubjectName()));			
				result.setTenantId(loggedinuser.getTenantId());
				resultService.saveOrUpdateResult(result);
			}else{
				String subjectCode = null;
				Set<String> keySet = csvValues.keySet();
				for (String string : keySet) {	
					if(string.contains("#")){
						String subjectHeader = string.split("-")[0];
						subjectCode = subjectHeader.split("#")[1];
						subject = subjectService.getSubjectByCode(subjectCode);
						Result result = new Result();
						result.setClassYear(classYear);
						result.setSection(section);
						result.setExamination(exam);
						result.setSubject(subject);
						result.setAcademic(academic);
						result.setUser(user);
						result.setMark(Integer.parseInt(csvValues.get("subjectCode#"+subject.getCode()+"-"+subject.getSubjectName())));			
						result.setTenantId(loggedinuser.getTenantId());
						logger.info("Student Mark: "+csvValues.get("subjectCode#"+subject.getCode()+"-"+subject.getSubjectName()));
						resultService.saveOrUpdateResult(result);
					}					
				}				
			}
			
		}catch (Exception e) {
			e.printStackTrace();
		}			
	}
	
	public void saveSection(Map<String, String> csvValues) throws Exception{
		ClassYear classYear = classYearService.getClassYearByName(csvValues.get("Class"));
		User loggedinuser = SecurityUtil.getThreadLocalUser().get();
		Section section =new Section();
		section.setTenantId(loggedinuser.getTenantId());
		section.setClassYear(classYear);
		section.setSectionName(csvValues.get("Section"));
		section.setStatus("Active");
		sectionService.saveOrUpdate(section);
		
	}
	
	public void saveStaff(Map<String, String> csvValues) throws Exception{
		User loggedinuser = SecurityUtil.getThreadLocalUser().get();
		Staff staff = new Staff();
		staff.setFirstName(csvValues.get("firstName"));
		staff.setLastName(csvValues.get("lastName"));
		staff.setMartialStatus(csvValues.get("martialStatus"));
		staff.setGender(csvValues.get("gender"));
		staff.setQualification(csvValues.get("qualification"));
		staff.setContactNumber(csvValues.get("contactNumber"));
		staff.setTenantId(loggedinuser.getTenantId());
		staffService.saveOrUpdateStaff(staff);
			
	}
	
	public void saveStudent(Map<String, String> csvValues) throws Exception{
		//ClassYear classYear = classYearService.getClassYearByName(getClassYear());
		//Section section = sectionService.getSectionByName(getSectionName());
		User loggedinuser = SecurityUtil.getThreadLocalUser().get();
		User user = new User();
		user.setClassYear(getClassYear());
		user.setSection(getSectionName());
		user.setUsername(csvValues.get("username"));
		user.setFirstName(csvValues.get("firstName"));
		user.setLastName(csvValues.get("lastName"));
		user.setEmail(csvValues.get("email"));
		user.setPhoneNumber(csvValues.get("phoneNumber"));
		user.setAddress(csvValues.get("address"));
		user.setTenantId(loggedinuser.getTenantId());
		user.setEnabled(true);
		user.setPassword(csvValues.get("username"));
		user.addRole(roleManager.getRole("ROLE_USER"));
		userManager.saveUser(user);
		
	}
	
	public void saveSubject(Map<String, String> csvValues) throws Exception{
		ClassYear classYear = classYearService.getClassYearByName(csvValues.get("Class"));
		User loggedinuser = SecurityUtil.getThreadLocalUser().get();
		Subject subject =new Subject();
		subject.setClassYear(classYear);
		subject.setSubjectName(csvValues.get("SubjectName"));
		subject.setCode(csvValues.get("SubjectCode"));
		subject.setTenantId(loggedinuser.getTenantId());
		subject.setStatus("Active");
		subjectService.saveOrUpdateSubject(subject);
			
		}
	
	public void saveExamination(Map<String, String> csvValues) throws Exception{
		ClassYear classYear = classYearService.getClassYearByName(csvValues.get("Class"));
		User loggedinuser = SecurityUtil.getThreadLocalUser().get();
		Examination exam =new Examination();
		exam.setTenantId(loggedinuser.getTenantId());
		exam.setClassYear(classYear);
		exam.setExamName(csvValues.get("Examination"));
		exam.setStatus("Active");
		examService.saveOrUpdateExam(exam);		
		
	}
	
	public void saveClassYear(Map<String, String> csvValues) throws Exception{
		User loggedinuser = SecurityUtil.getThreadLocalUser().get();
		ClassYear classYear = new ClassYear();
		classYear.setTenantId(loggedinuser.getTenantId());
		classYear.setStatus("Active");
		classYear.setName(csvValues.get("Class"));
		classYearService.saveOrUpdate(classYear);
	}
	
	public File getFileUpload() {
		return fileUpload;
	}
	
	public void setFileUpload(File fileUpload) {
		this.fileUpload = fileUpload;
	}
	
	public InputStream getFileInputStream() {
		return fileInputStream;
	}

	public String getScreenName() {
		return screenName;
	}

	public void setScreenName(String screenName) {
		this.screenName = screenName;
	}
	
	public String getFilename() {
		return filename;
	}

	public void setFilename(String filename) {
		this.filename = filename;
	}

	public ImportFileService getImportFileService() {
		return importFileService;
	}

	public void setImportFileService(ImportFileService importFileService) {
		this.importFileService = importFileService;
	}

	public ResultService getResultService() {
		return resultService;
	}

	public void setResultService(ResultService resultService) {
		this.resultService = resultService;
	}

	public ExaminationService getExamService() {
		return examService;
	}

	public void setExamService(ExaminationService examService) {
		this.examService = examService;
	}

	public ClassYearService getClassYearService() {
		return classYearService;
	}

	public void setClassYearService(ClassYearService classYearService) {
		this.classYearService = classYearService;
	}

	public AcademicService getAcademicService() {
		return academicService;
	}

	public void setAcademicService(AcademicService academicService) {
		this.academicService = academicService;
	}

	public SectionService getSectionService() {
		return sectionService;
	}

	public void setSectionService(SectionService sectionService) {
		this.sectionService = sectionService;
	}

	public UserManager getUserManager() {
		return userManager;
	}

	public void setUserManager(UserManager userManager) {
		this.userManager = userManager;
	}

	public SubjectService getSubjectService() {
		return subjectService;
	}

	public void setSubjectService(SubjectService subjectService) {
		this.subjectService = subjectService;
	}

	public StaffService getStaffService() {
		return staffService;
	}

	public void setStaffService(StaffService staffService) {
		this.staffService = staffService;
	}

	public RoleManager getRoleManager() {
		return roleManager;
	}

	public void setRoleManager(RoleManager roleManager) {
		this.roleManager = roleManager;
	}

	public List<Academic> getAcademicList() {
		return academicList;
	}

	public void setAcademicList(List<Academic> academicList) {
		this.academicList = academicList;
	}

	public List<Examination> getExamList() {
		return examList;
	}

	public void setExamList(List<Examination> examList) {
		this.examList = examList;
	}

	public List<ClassYear> getClassYears() {
		return classYears;
	}

	public void setClassYears(List<ClassYear> classYears) {
		this.classYears = classYears;
	}

	public List<Section> getSectionList() {
		return sectionList;
	}

	public void setSectionList(List<Section> sectionList) {
		this.sectionList = sectionList;
	}

	public String getAcademicYear() {
		return academicYear;
	}

	public void setAcademicYear(String academicYear) {
		this.academicYear = academicYear;
	}

	public String getClassYear() {
		return classYear;
	}

	public void setClassYear(String classYear) {
		this.classYear = classYear;
	}

	public String getSectionName() {
		return sectionName;
	}

	public void setSectionName(String sectionName) {
		this.sectionName = sectionName;
	}

	public String getExamName() {
		return examName;
	}

	public void setExamName(String examName) {
		this.examName = examName;
	}

	public List<Subject> getSubjectList() {
		return subjectList;
	}

	public void setSubjectList(List<Subject> subjectList) {
		this.subjectList = subjectList;
	}

	public String getSubjectName() {
		return subjectName;
	}

	public void setSubjectName(String subjectName) {
		this.subjectName = subjectName;
	}	
}
